using SCADAEditor.Component;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;


namespace SCADAEditor.Container
{
    /// <summary>
    /// 画布容器类，用于承载和管理所有组态组件
    /// </summary>
    public class CanvasContainer : Control
    {
        private Size _contentSize = new Size(800, 600); // 内容区域大小
        private HScrollBar hScrollBar = new HScrollBar();
        private VScrollBar vScrollBar = new VScrollBar();
        private Point _viewOffset = Point.Empty; // 视图偏移量

        private enum ResizeHandle
        {
            None,
            TopLeft, Top, TopRight,
            Left, Right,
            BottomLeft, Bottom, BottomRight
        }
        
        // 当前选中的组件对象
        private ComponentBase _selectedComponent;
        // 当前操作的调整控制点类型(无/左上/上/右上/左/右/左下/下/右下)
        private ResizeHandle _currentHandle = ResizeHandle.None;
        // 鼠标拖动起始位置坐标
        private Point _dragStartPosition;
        // 组件原始边界矩形(用于大小调整时计算增量)
        private Rectangle _originalBounds;

        /// <summary>
        /// 当前画布上的所有组件集合
        /// </summary>
        public List<ComponentBase> Components { get; } = new List<ComponentBase>();

        // 新增框选相关字段
        private Point _selectionStart;
        private Rectangle _selectionRect;
        private bool _isSelecting = false;

        public CanvasContainer()
        {
            this.AllowDrop = true;  // 必须设置此项
              // 启用双缓冲
            this.DoubleBuffered = true;

            // 初始化滚动条
            hScrollBar.Dock = DockStyle.Bottom;
            vScrollBar.Dock = DockStyle.Right;
            
            hScrollBar.Scroll += (s, e) => {
                _viewOffset.X = e.NewValue;
                Invalidate();
            };
            
            vScrollBar.Scroll += (s, e) => {
                _viewOffset.Y = e.NewValue;
                Invalidate();
            };
            
            this.Controls.Add(hScrollBar);
            this.Controls.Add(vScrollBar);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            UpdateScrollBars();
        }

        private void UpdateScrollBars()
        {
            // 更新水平滚动条
            hScrollBar.Enabled = _contentSize.Width > this.ClientSize.Width;
            hScrollBar.Maximum = _contentSize.Width;
            hScrollBar.LargeChange = this.ClientSize.Width;
            
            // 更新垂直滚动条
            vScrollBar.Enabled = _contentSize.Height > this.ClientSize.Height;
            vScrollBar.Maximum = _contentSize.Height;
            vScrollBar.LargeChange = this.ClientSize.Height;
        }

       
        public Size ContentSize
        {
            get { return _contentSize; }
            set 
            {
                _contentSize = value;
                UpdateScrollBars();
                Invalidate();
            }
        }


        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);  // 调用基类鼠标按下事件处理

    
            // // 清除所有组件的选中状态
            // foreach (var component in Components)
            // {
            //     component.IsSelected = false;
            // }

            // 如果不是点击组件或控制点，开始框选
            if (!Components.Any(c => c.IsEditMode && c.HitTest(e.Location)))
            {
                _isSelecting = true;
                _selectionStart = e.Location;
                _selectionRect = new Rectangle(e.Location, Size.Empty);
            }

             // 检查是否点击了空白区域
            bool clickedOnComponent = Components.Any(c => c.IsEditMode && c.HitTest(e.Location));
             
            var clickedComponent = Components.LastOrDefault(c => c.IsEditMode && c.HitTest(e.Location));
             // 如果点击的组件未被选中，清除所有选中状态
            if (clickedComponent != null && !clickedComponent.IsSelected)
            {
                foreach (var component in Components)
                {
                    component.IsSelected = false;
                }
            }
            // // 清除所有组件的选中状态
            // foreach (var component in Components)
            // {
            //     component.IsSelected = false;
            // }

            // 如果是空白区域点击，直接返回并重绘
            if (!clickedOnComponent)
            {
                foreach (var component in Components)
                {
                    component.IsSelected = false;
                }
                _selectedComponent = null;
                Invalidate();
                return;
            }
          
             // 先检查是否点击了任何组件的控制点
            foreach (var component in Components.Where(c => c.IsEditMode))
            {
                _selectedComponent = component;
                _currentHandle = GetResizeHandleAtPoint(e.Location);
        
                if (_currentHandle != ResizeHandle.None)
                {
                    _dragStartPosition = e.Location;
                    _originalBounds = new Rectangle(component.Position, component.Size);
                     Invalidate(); // 立即重绘显示控制点
                    return;
                }
            }

         
            // 如果没有点击控制点，则选择组件
            _selectedComponent = Components.LastOrDefault(c => 
                c.IsEditMode && c.HitTest(e.Location));
    
            // 如果选中了组件，准备拖动
            if (_selectedComponent != null)
            {
                _selectedComponent.IsSelected = true;
                _dragStartPosition = e.Location;
                _originalBounds = new Rectangle(_selectedComponent.Position, _selectedComponent.Size);
                Invalidate(); // 立即重绘显示控制点
            }
            
      
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);  // 调用基类鼠标移动事件处理

            if (_isSelecting && e.Button == MouseButtons.Left)
            {
                // 更新选择矩形
                int x = Math.Min(_selectionStart.X, e.X);
                int y = Math.Min(_selectionStart.Y, e.Y);
                int width = Math.Abs(e.X - _selectionStart.X);
                int height = Math.Abs(e.Y - _selectionStart.Y);
                
                _selectionRect = new Rectangle(x, y, width, height);
                Invalidate();
            }
            
            // 如果不是左键按下则直接返回
            if (e.Button != MouseButtons.Left) return;

            if (_selectedComponent != null && _selectedComponent.IsEditMode)
            {
                if (_currentHandle != ResizeHandle.None)
                {
                    // 调整大小逻辑
                    if (_selectedComponent != null && _selectedComponent.IsEditMode && _currentHandle != ResizeHandle.None)
                    {
                        // 计算鼠标移动的增量（相对于拖动起始位置）
                        var deltaX = e.X - _dragStartPosition.X;
                        var deltaY = e.Y - _dragStartPosition.Y;

                        // 应用平滑处理：只有当移动距离超过1像素时才执行调整
                        if (Math.Abs(deltaX) > 1 || Math.Abs(deltaY) > 1)
                        {
                            // 调用调整组件大小的方法
                            ResizeComponent(new Point(deltaX, deltaY));

                            // 触发重绘
                            Invalidate();
                        }
                    }
                }
                else
                {
                    // // 拖动组件逻辑
                    // var deltaX = e.X - _dragStartPosition.X;
                    // var deltaY = e.Y - _dragStartPosition.Y;
            
                    // if (Math.Abs(deltaX) > 1 || Math.Abs(deltaY) > 1)
                    // {
                    //     _selectedComponent.Position = new Point(
                    //         _originalBounds.X + deltaX,
                    //         _originalBounds.Y + deltaY);
                    //     Invalidate();
                    // }
                     // 拖动组件逻辑
            var deltaX = e.X - _dragStartPosition.X;
            var deltaY = e.Y - _dragStartPosition.Y;
    
            if (Math.Abs(deltaX) > 1 || Math.Abs(deltaY) > 1)
            {
                // 移动所有选中的组件
                foreach (var component in Components.Where(c => c.IsSelected))
                {
                    component.Position = new Point(
                        component.Position.X + deltaX,
                        component.Position.Y + deltaY);
                }
                
                // 更新拖动起始位置
                _dragStartPosition = e.Location;
                Invalidate();
            }
                }
            }
            
         
        }
        
       
        protected override void OnMouseUp(MouseEventArgs e)
        {
               if (_isSelecting)
        {
            // 选中矩形区域内的所有组件
            foreach (var component in Components.Where(c => c.IsEditMode))
            {
                if (_selectionRect.IntersectsWith(new Rectangle(component.Position, component.Size)))
                {
                    component.IsSelected = true;
                }
            }
            
            _isSelecting = false;
            _selectionRect = Rectangle.Empty;
            Invalidate();
        }
        
          
            _currentHandle = ResizeHandle.None;
              base.OnMouseUp(e);
        }

        /// <summary>
        /// 根据鼠标位置获取当前点击的控制点类型
        /// </summary>
        /// <param name="point">鼠标位置</param>
        /// <returns>当前点击的控制点类型</returns>
        private ResizeHandle GetResizeHandleAtPoint(Point point)
        {
            if (_selectedComponent == null) return ResizeHandle.None;  // 如果没有选中组件则返回None
            
            var rect = new Rectangle(_selectedComponent.Position, _selectedComponent.Size);
            const int handleSize = 8;  // 控制点大小设置为8像素
            
            // 检查8个控制点是否包含当前鼠标位置
            if (new Rectangle(rect.Left - handleSize/2, rect.Top - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.TopLeft;  // 左上角控制点
            if (new Rectangle(rect.Right - handleSize/2, rect.Top - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.TopRight;  // 右上角控制点
            if (new Rectangle(rect.Left - handleSize/2, rect.Bottom - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.BottomLeft;  // 左下角控制点
            if (new Rectangle(rect.Right - handleSize/2, rect.Bottom - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.BottomRight;  // 右下角控制点
            if (new Rectangle(rect.Left + rect.Width/2 - handleSize/2, rect.Top - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.Top;  // 上边中点控制点
            if (new Rectangle(rect.Left + rect.Width/2 - handleSize/2, rect.Bottom - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.Bottom;  // 下边中点控制点
            if (new Rectangle(rect.Left - handleSize/2, rect.Top + rect.Height/2 - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.Left;  // 左边中点控制点
            if (new Rectangle(rect.Right - handleSize/2, rect.Top + rect.Height/2 - handleSize/2, handleSize, handleSize).Contains(point))
                return ResizeHandle.Right;  // 右边中点控制点
            
            return ResizeHandle.None;  // 没有点击任何控制点
        }

        private void ResizeComponent(Point delta)
        {
             // 添加最小移动阈值
            if (Math.Abs(delta.X) < 1 && Math.Abs(delta.Y) < 1) return;
            var newBounds = _originalBounds;
            
            switch (_currentHandle)
            {
                case ResizeHandle.TopLeft:
                    newBounds.X += delta.X;
                    newBounds.Y += delta.Y;
                    newBounds.Width -= delta.X;
                    newBounds.Height -= delta.Y;
                    break;
                case ResizeHandle.Top:
                    newBounds.Y += delta.Y;
                    newBounds.Height -= delta.Y;
                    break;
                case ResizeHandle.TopRight:
                    newBounds.Y += delta.Y;
                    newBounds.Width += delta.X;
                    newBounds.Height -= delta.Y;
                    break;
                case ResizeHandle.Left:
                    newBounds.X += delta.X;
                    newBounds.Width -= delta.X;
                    break;
                case ResizeHandle.Right:
                    newBounds.Width += delta.X;
                    break;
                case ResizeHandle.BottomLeft:
                    newBounds.X += delta.X;
                    newBounds.Width -= delta.X;
                    newBounds.Height += delta.Y;
                    break;
                case ResizeHandle.Bottom:
                    newBounds.Height += delta.Y;
                    break;
                case ResizeHandle.BottomRight:
                    newBounds.Width += delta.X;
                    newBounds.Height += delta.Y;
                    break;
            }
            
            // 确保最小尺寸
            if (newBounds.Width < 10) newBounds.Width = 10;
            if (newBounds.Height < 10) newBounds.Height = 10;
            
            _selectedComponent.Position = newBounds.Location;
            _selectedComponent.Size = newBounds.Size;
        }
            
        /// <summary>
        /// 向画布添加新组件
        /// </summary>
        /// <param name="component">要添加的组件对象</param>
        public void AddComponent(ComponentBase component)
        {
            Components.Add(component);
            Invalidate(); // 触发重绘
        }

        /// <summary>
        /// 重写绘制方法，渲染所有组件
        /// </summary>
        /// <param name="e">绘制事件参数</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);
            // 使用双缓冲后，不需要调用base.OnPaint(e)
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // 应用视图偏移
            e.Graphics.TranslateTransform(-_viewOffset.X, -_viewOffset.Y);
            
            // 绘制内容
            foreach (var component in Components)
            {
                component.Draw(e.Graphics);
            }
            
            // 绘制容器边界
            using (var pen = new Pen(Color.Gray, 1) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash })
            {
                e.Graphics.DrawRectangle(pen, new Rectangle(Point.Empty, _contentSize));
            }
            
            // 恢复变换
            e.Graphics.ResetTransform();


            // 绘制选择矩形（虚线框）
            if (_isSelecting && !_selectionRect.IsEmpty)
            {
                using (var pen = new Pen(Color.Blue, 1) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash })
                {
                    e.Graphics.DrawRectangle(pen, _selectionRect);
                }
            }

              // 添加边框绘制
            using (var borderPen = new Pen(Color.Black, 1))
            {
                e.Graphics.DrawRectangle(borderPen, new Rectangle(0, 0, Width - 1, Height - 1));
            }
        }

        /// <summary>
        /// 将当前画布状态保存为JSON字符串
        /// </summary>
        /// <returns>包含所有组件状态的JSON字符串</returns>
        public string SaveToJson()
        {
            // 序列化逻辑
            return "";
        }

        /// <summary>
        /// 从JSON字符串加载画布状态
        /// </summary>
        /// <param name="json">包含组件状态的JSON字符串</param>
        public void LoadFromJson(string json)
        {
            // 反序列化逻辑
        }
    }
}